package com.xiebishe.mylibrary.base

import androidx.annotation.MainThread
import androidx.lifecycle.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import net.sqlcipher.BuildConfig
import kotlin.coroutines.CoroutineContext
import kotlin.system.exitProcess

open class BaseViewModel : ViewModel(), CoroutineScope {

    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Main+job
    @Volatile
    private var active: Boolean = true
    private val job = SupervisorJob()


    override fun onCleared() {
        job.cancel()
        active = false
    }


    companion object {
        const val PAGE_STATE_LOADING = 1
        const val PAGE_STATE_ERROR = -1
        const val PAGE_STATE_CONTENT = 0
        const val PAGE_STATE_EMPTY = 2
        const val PAGE_STATE_NO_MORE = 3
        const val PAGE_STATE_NEXT_PRE_ERROR = 4
        const val PAGE_STATE_NEXT_PRE_CONTENT = 5
    }
}


fun <T> LiveData<T>.observe(lifecycleOwner: LifecycleOwner, block: (t: T?) -> Unit) {
    observe(lifecycleOwner, Observer {
        try {
            block(it)
        } catch (e: Throwable) {
            if (BuildConfig.DEBUG) {
                Thread.currentThread().uncaughtExceptionHandler.uncaughtException(Thread.currentThread(), e)
                android.os.Process.killProcess(android.os.Process.myPid())
                System.exit(1)
            }
        }
    })
}
fun <T> LiveData<T>.observe2(lifecycleOwner: LifecycleOwner, block: (t: T?) -> Unit) {
    observe(lifecycleOwner, Observer {
        try {
            block(it)
        } catch (e: Throwable) {
            if (BuildConfig.DEBUG) {
                Thread.currentThread().uncaughtExceptionHandler.uncaughtException(Thread.currentThread(), e)
                android.os.Process.killProcess(android.os.Process.myPid())
                exitProcess(1)
            }
        }
    })
}
class SingleLiveEvent<T> : MutableLiveData<T>() {
    private var handled = false
    private val map = HashMap<Observer<in T>, Observer<in T>>()
    override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
        val warpObserver = Observer<T> {
            if (!handled) {
                handled = true
                observer.onChanged(it)
            }
        }
        map[observer] = warpObserver
        super.observe(owner, warpObserver)
    }

    override fun observeForever(observer: Observer<in T>) {
        val warpObserver = Observer<T> {
            if (!handled) {
                handled = true
                observer.onChanged(it)
            }
        }
        map[observer] = warpObserver
        super.observeForever(warpObserver)
    }

    override fun removeObserver(observer: Observer<in T>) {
        val observer1 = map[observer]
        if (observer1 == null) {
            super.removeObserver(observer)
        } else {
            map.remove(observer)
            super.removeObserver(observer1)
        }
    }

    override fun setValue(value: T?) {
        handled = false
        super.setValue(value)
    }

    @MainThread
    fun call() {
        value = null
    }

}